package com.sky.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.api.coupon.CouponFeignService;
import com.sky.api.search.SearchFeignService;
import com.sky.api.ware.WareFeignService;
import com.sky.constant.ProductConstant;
import com.sky.domain.*;
import com.sky.dto.MemberPriceDTO;
import com.sky.dto.SkuReductionDTO;
import com.sky.dto.SkuStockVO;
import com.sky.dto.SmsSpuBoundsDTO;
import com.sky.dto.es.ProductModel;
import com.sky.exception.BizException;
import com.sky.service.*;
import com.sky.mapper.PmsSpuInfoMapper;
import com.sky.to.product.SpuInfoTo;
import com.sky.utils.PageUtils;
import com.sky.utils.R;
import com.sky.utils.StringUtils;
import com.sky.vo.param.PmsSpuInfoVo;
import com.sky.vo.sku.*;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【pms_spu_info(spu信息)】的数据库操作Service实现
* @createDate 2024-06-30 16:46:42
*/
@Service
public class PmsSpuInfoServiceImpl extends ServiceImpl<PmsSpuInfoMapper, PmsSpuInfo> implements PmsSpuInfoService{

    @Resource
    private PmsSpuInfoDescService pmsSpuInfoDescService;
    @Resource
    private PmsSpuImagesService pmsSpuImagesService;
    @Resource
    private PmsProductAttrValueService pmsProductAttrValueService;
    @Resource
    private PmsAttrService pmsAttrService;
    @Resource
    private PmsSkuInfoService pmsSkuInfoService;
    @Resource
    private PmsSkuImagesService pmsSkuImagesService;
    @Resource
    private PmsSkuSaleAttrValueService pmsSkuSaleAttrValueService;
    @Resource
    private CouponFeignService couponFeignService;
    @Resource
    private PmsBrandService pmsBrandService;
    @Resource
    private PmsCategoryService pmsCategoryService;
    @Resource
    private WareFeignService wareFeignService;
    @Resource
    private SearchFeignService searchFeignService;


    @Override
    @GlobalTransactional
    public boolean addSpuInfo(SpuInfoAddVo spuInfoAddVo) {
        // 1 保存spu信息(pms_spu_info)
        PmsSpuInfo spuInfo = new PmsSpuInfo();
        BeanUtils.copyProperties(spuInfoAddVo, spuInfo);
        baseMapper.insert(spuInfo);
        // 2 保存spu描述信息(pms_spu_info_desc)
        PmsSpuInfoDesc spuInfoDesc = new PmsSpuInfoDesc();
        spuInfoDesc.setSpuId(spuInfo.getId());
        spuInfoDesc.setDecript(StringUtils.join(spuInfoAddVo.getDecript(), ","));
        pmsSpuInfoDescService.save(spuInfoDesc);
        // 3 保存spu商品图片信息(pms_spu_images)
        List<String> images = spuInfoAddVo.getImages();
        if (StringUtils.isNotEmpty(images)) {
            Set<PmsSpuImages> imagesSet = images.stream().map(image -> {
                PmsSpuImages spuImages = new PmsSpuImages();
                spuImages.setSpuId(spuInfo.getId());
                spuImages.setImgUrl(image);
                return spuImages;
            }).collect(Collectors.toSet());
            pmsSpuImagesService.saveBatch(imagesSet);
        }
        // 4 保存spu的规格参数(pms_product_attr_value)
        List<BaseAttrs> baseAttrs = spuInfoAddVo.getBaseAttrs();
        if (StringUtils.isNotEmpty(baseAttrs)) {
            Set<PmsProductAttrValue> pmsProductAttrValueSet = baseAttrs.stream().map(baseAttr -> {
                PmsProductAttrValue pmsProductAttrValue = new PmsProductAttrValue();
                pmsProductAttrValue.setSpuId(spuInfo.getId());
                pmsProductAttrValue.setAttrId(baseAttr.getAttrId());
                PmsAttr pmsAttr = pmsAttrService.getById(baseAttr.getAttrId());
                if (StringUtils.isNotNull(pmsAttr)){
                    pmsProductAttrValue.setAttrName(pmsAttr.getAttrName());
                }
                pmsProductAttrValue.setAttrValue(baseAttr.getAttrValues());
                pmsProductAttrValue.setQuickShow(baseAttr.getShowDesc());
                return pmsProductAttrValue;
            }).collect(Collectors.toSet());
            pmsProductAttrValueService.saveBatch(pmsProductAttrValueSet);
        }
        // 5 保存sku基本信息(pms_sku_info)
        List<SkuInfoAddVo> skuInfoAddVos = spuInfoAddVo.getSkus();
        if (StringUtils.isNotEmpty(skuInfoAddVos)) {
            for (SkuInfoAddVo skuInfoAddVo : skuInfoAddVos) {
                PmsSkuInfo skuInfo = new PmsSkuInfo();
                BeanUtils.copyProperties(skuInfoAddVo, skuInfo);
                skuInfo.setSpuId(spuInfo.getId());
                skuInfo.setCatalogId(spuInfo.getCatalogId());
                skuInfo.setBrandId(spuInfo.getBrandId());
                skuInfo.setSaleCount(0L);
                List<String> descar = skuInfoAddVo.getDescar();
                if (StringUtils.isNotEmpty(descar)){
                    skuInfo.setSkuDesc(StringUtils.join(descar, ","));
                }
                // 查询sku的默认图片
                List<Images> imagesList = skuInfoAddVo.getImages();
                if (StringUtils.isNotEmpty(imagesList)){
                    for (Images image : imagesList) {
                        if (1 == image.getDefaultImg()) {
                            skuInfo.setSkuDefaultImg(image.getImgUrl());
                        }
                    }
                }
                pmsSkuInfoService.save(skuInfo);

                // 5.1 保存sku的图片信息(pms_sku_images)
                if (StringUtils.isNotEmpty(imagesList)) {
                    Set<PmsSkuImages> imagesSet = imagesList.stream().map(image -> {
                        PmsSkuImages pmsSkuImages = new PmsSkuImages();
                        BeanUtils.copyProperties(image, pmsSkuImages);
                        pmsSkuImages.setSkuId(skuInfo.getSkuId());
                        return pmsSkuImages;
                    }).collect(Collectors.toSet());
                    pmsSkuImagesService.saveBatch(imagesSet);
                }

                // 5.2 保存sku的销售属性信息(pms_sku_sale_attr_value)
                List<Attr> attr = skuInfoAddVo.getAttr();
                if (StringUtils.isNotEmpty(attr)) {
                    Set<PmsSkuSaleAttrValue> pmsSkuSaleAttrValueSet = attr.stream().map(data -> {
                        PmsSkuSaleAttrValue pmsSkuSaleAttrValue = new PmsSkuSaleAttrValue();
                        BeanUtils.copyProperties(data, pmsSkuSaleAttrValue);
                        pmsSkuSaleAttrValue.setSkuId(skuInfo.getSkuId());
                        return pmsSkuSaleAttrValue;
                    }).collect(Collectors.toSet());
                    pmsSkuSaleAttrValueService.saveBatch(pmsSkuSaleAttrValueSet);
                }

                // 5.3 保存sku的积分信息
                if (skuInfoAddVo.getFullCount() > 0 || skuInfoAddVo.getFullPrice().compareTo(new BigDecimal("0")) > 0){
                    SkuReductionDTO skuReductionDTO = new SkuReductionDTO();
                    skuReductionDTO.setSkuId(skuInfo.getSkuId());
                    BeanUtils.copyProperties(skuInfoAddVo, skuReductionDTO);
                    List<MemberPrice> memberPriceList = skuInfoAddVo.getMemberPrice();
                    if (StringUtils.isNotEmpty(memberPriceList)) {
                        List<MemberPriceDTO> memberPriceDTOList = memberPriceList.stream().map(memberPrice -> {
                            MemberPriceDTO memberPriceDTO = new MemberPriceDTO();
                            BeanUtils.copyProperties(memberPrice, memberPriceDTO);
                            return memberPriceDTO;
                        }).collect(Collectors.toList());
                        skuReductionDTO.setMemberPrice(memberPriceDTOList);
                    }
                    R r = couponFeignService.addSkuReduction(skuReductionDTO);
                }
            }
        }

        // 6 保存spu的积分信息(sms_spu_bounds)
        Bounds bounds = spuInfoAddVo.getBounds();
        SmsSpuBoundsDTO smsSpuBoundsDTO = new SmsSpuBoundsDTO();
        BeanUtils.copyProperties(bounds, smsSpuBoundsDTO);
        smsSpuBoundsDTO.setSpuId(spuInfo.getId());
        R r = couponFeignService.addSpuBounds(smsSpuBoundsDTO);

        return true;
    }

    /**
     * 分页查询spu信息
     * @param vo
     * @return
     */
    @Override
    public PageUtils pageQuery(PmsSpuInfoVo vo) {
        if (StringUtils.isNotEmpty(vo.getKey())){
            vo.setSpuName(vo.getKey());
        }
        if (StringUtils.isNotEmpty(vo.getStatus())){
            vo.setPublishStatus(vo.getStatus());
        }
        PageUtils pageUtils = PageUtils.selectPage(baseMapper, vo, PmsSpuInfo.class);
        return pageUtils;
    }

    /**
     * 上架
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean up(Long id) {
        // 商品属性
        List<PmsProductAttrValue> pmsProductAttrValueList = pmsProductAttrValueService.list(new LambdaQueryWrapper<PmsProductAttrValue>()
                .eq(PmsProductAttrValue::getSpuId, id));
        // 过滤出需要检索的属性
        List<ProductModel.Attr> productAttrList = new ArrayList<>();
        if (StringUtils.isNotEmpty(pmsProductAttrValueList)){
            // 获取属性id集合
            Set<Long> set = pmsProductAttrValueList.stream().map(PmsProductAttrValue::getAttrId).collect(Collectors.toSet());
            // 获取检索属性
            List<PmsAttr> attrList = pmsAttrService.list(new LambdaQueryWrapper<PmsAttr>()
                    .eq(PmsAttr::getSearchType, 1)
                    .in(PmsAttr::getAttrId, set));
            if (StringUtils.isNotEmpty(attrList)){
                // 获取检索属性id集合
                List<Long> attrIds = attrList.stream().map(PmsAttr::getAttrId).collect(Collectors.toList());
                // 过滤出spu真正需要检索的属性
                pmsProductAttrValueList = pmsProductAttrValueList.stream().filter(pmsProductAttrValue -> attrIds.contains(pmsProductAttrValue.getAttrId())).collect(Collectors.toList());
                if (StringUtils.isNotEmpty(pmsProductAttrValueList)){
                    // 封装成ProductModel.Attr
                    productAttrList = pmsProductAttrValueList.stream().map(pmsProductAttrValue -> {
                        ProductModel.Attr attr = new ProductModel.Attr();
                        BeanUtils.copyProperties(pmsProductAttrValue, attr);
                        return attr;
                    }).collect(Collectors.toList());
                }
            }
        }

        // 查询spu的sku信息
        List<PmsSkuInfo> skuInfoList = pmsSkuInfoService.list(new LambdaQueryWrapper<PmsSkuInfo>().eq(PmsSkuInfo::getSpuId, id));
        if (StringUtils.isNotEmpty(skuInfoList)){
            List<Long> list = skuInfoList.stream().map(PmsSkuInfo::getSkuId).collect(Collectors.toList());

            // 商品库存（调用远程服务查询库存）
            R<List<SkuStockVO>> skuStock = wareFeignService.getSkuStock(list);

            Map<Long, Boolean> stockMap = new HashMap<>();
            if (skuStock.getCode() == 0){
                List<SkuStockVO> voList = skuStock.getData();
                if (StringUtils.isNotEmpty(voList)){
                    stockMap = voList.stream().collect(Collectors.toMap(SkuStockVO::getSkuId, SkuStockVO::getHasStock));
                }
            }

            List<ProductModel.Attr> finalProductAttrList = productAttrList;
            Map<Long, Boolean> finalStockMap = stockMap;
            List<ProductModel> productModelList = skuInfoList.stream().map(skuInfo -> {
                ProductModel productModel = new ProductModel();
                BeanUtils.copyProperties(skuInfo, productModel);
                productModel.setSkuPrice(skuInfo.getPrice());
                productModel.setSkuImg(skuInfo.getSkuDefaultImg());
                productModel.setHotScore(0L);
                // 库存
                productModel.setHasStock(finalStockMap.get(skuInfo.getSkuId()));
                // 品牌信息
                PmsBrand pmsBrand = pmsBrandService.getById(skuInfo.getBrandId());
                productModel.setBrandName(pmsBrand.getName());
                productModel.setBrandImg(pmsBrand.getDescript());
                // 商品三级分类
                PmsCategory category = pmsCategoryService.getById(skuInfo.getCatalogId());
                productModel.setCatalogName(category.getName());
                // 商品的属性集合
                productModel.setAttrs(finalProductAttrList);

                return productModel;
            }).collect(Collectors.toList());
            // sku信息入库es
            R result = searchFeignService.addProductSkuInfo(productModelList);
            if (result.getCode() != 0){
                throw new BizException("远程调用失败");
            } else {
                this.update(null,new LambdaUpdateWrapper<PmsSpuInfo>()
                        .eq(PmsSpuInfo::getId,id)
                        .set(PmsSpuInfo::getPublishStatus, ProductConstant.PublishStatusEnum.UP_SPU.getCode()));
            }
        }
        return true;
    }

    /**
     * 下架
     * @param id
     * @return
     */
    @Override
    public boolean down(Long id) {
        this.update(null,new LambdaUpdateWrapper<PmsSpuInfo>()
                .eq(PmsSpuInfo::getId,id)
                .set(PmsSpuInfo::getPublishStatus, ProductConstant.PublishStatusEnum.DOWN_SPU.getCode()));
        return true;
    }

    /**
     * 根据skuId查询spu信息
     * @param skuId
     * @return
     */
    @Override
    public SpuInfoTo getSpuBySkuId(Long skuId) {
        PmsSkuInfo pmsSkuInfo = pmsSkuInfoService.getById(skuId);
        PmsSpuInfo pmsSpuInfo = baseMapper.selectById(pmsSkuInfo.getSpuId());
        SpuInfoTo spuInfoTo = new SpuInfoTo();
        BeanUtils.copyProperties(pmsSpuInfo,spuInfoTo);

        // 查询spu默认图片
        PmsSpuImages spuImages = pmsSpuImagesService.getOne(new LambdaQueryWrapper<PmsSpuImages>()
                .eq(PmsSpuImages::getSpuId, pmsSpuInfo.getId()).eq(PmsSpuImages::getDefaultImg, 1));
        if (spuImages != null){
            spuInfoTo.setSpuPic(JSON.toJSONString(spuImages));
        }

        // 查询spu的品牌名称
        PmsBrand pmsBrand = pmsBrandService.getById(pmsSpuInfo.getBrandId());
        spuInfoTo.setSpuBrand(pmsBrand.getName());

        // 查询spu的商品分类信息
        PmsCategory pmsCategory = pmsCategoryService.getById(pmsSpuInfo.getCatalogId());
        spuInfoTo.setCatalogId(pmsCategory.getCatId());

        return spuInfoTo;
    }
}




